package exam_ctrl

import (
	"net/http"
	"net/url"
	"os"
	"ubt-aio-service/app/mod/exam_mod"
	"ubt-aio-service/app/mod/sys_mod"
	"ubt-aio-service/app/pkg/parse"
	"ubt-aio-service/app/serv/exam_serv"
	"ubt-aio-service/app/serv/sys_serv"
	"ubt-aio-service/app/utils"
)

type examLog struct{}

var ExamLogCtrl examLog

// OneExam 获取试卷详情
func (c *examLog) OneExam(r *http.Request, w http.ResponseWriter) {
	// 过滤关键参数值中的非法字符
	u := r.URL.Query()
	if u == nil {
		utils.ToJson(w, utils.ParamErr)
		return
	}
	examId := u.Get("examId")
	// 过滤关键参数值中的非法字符
	examId = utils.InputFilter(examId, true)
	if examId == "" || len(examId) != 21 {
		utils.ToJson(w, utils.ParamErr)
		return
	}
	res := exam_serv.ExamLogServ.OneExam(examId)
	utils.ToJson(w, res)
}

// ListQsts 获取试题列表
func (c *examLog) ListQsts(r *http.Request, w http.ResponseWriter) {
	// 过滤关键参数值中的非法字符
	u := r.URL.Query()
	if u == nil {
		utils.ToJson(w, utils.ParamErr)
		return
	}
	examId := u.Get("examId")
	// 过滤关键参数值中的非法字符
	examId = utils.InputFilter(examId, true)
	if examId == "" || len(examId) != 21 {
		utils.ToJson(w, utils.ParamErr)
		return
	}
	// 获取试卷的配置信息
	req := exam_serv.ExamServ.List(examId)
	var qstList []map[string]any
	if req.Code == utils.Succeed.Code {
		// 从缓冲中获取题目选项
		optRes := exam_serv.ExamLogServ.ListOpts()
		for _, examOpt := range req.Data.([]map[string]any) {
			// 如果配置的题目数量大于0
			limit := examOpt["nums"].(int64)
			if limit > 0 {
				vo := &exam_mod.QstSelReq{
					Kind:  examOpt["kind"].(int64),
					Limit: limit,
				}
				qstRes := exam_serv.ExamLogServ.ListQsts(vo)
				if qstRes.Code == utils.Succeed.Code {
					for _, qst := range qstRes.Data.([]map[string]any) {
						qst["score"] = examOpt["score"]
						qst["optList"] = make([]map[string]any, 0)
						for _, opt := range optRes.Data.([]map[string]any) {
							if qst["qstId"] == opt["qstId"] {
								qst["optList"] = append(qst["optList"].([]map[string]any), opt)
							}
						}
					}
					qstList = append(qstList, qstRes.Data.([]map[string]any)...)
				}
			}
		}
		if len(qstList) > 0 {
			utils.ToJson(w, &utils.ResJson{Code: utils.Succeed.Code, Data: qstList})
			return
		}
	}
	utils.ToJson(w, utils.NoData)
}

// TestExam 提交答卷
func (c *examLog) TestExam(r *http.Request, w http.ResponseWriter) {
	req := &exam_mod.ExamLogSaveReq{}
	// 将请求的参数转换为请求结构体
	if err := parse.Parse(r, req); err != "" {
		utils.ToJson(w, &utils.ResJson{Code: utils.ParamErr.Code, Msg: err})
		return
	}
	// 过滤关键参数值中的非法字符
	req.LogId = utils.InputFilter(req.LogId, true)
	req.RealName = utils.InputFilter(req.RealName, true)
	req.Mobile = utils.InputFilter(req.Mobile, true)
	req.WorkNo = utils.InputFilter(req.WorkNo, true)
	req.DeptName = utils.InputFilter(req.DeptName, true)
	// 新增
	res := exam_serv.ExamLogServ.Add(req)
	if res.Code == utils.Succeed.Code {
		ch := make(chan int)
		go exam_serv.ExamLogServ.AddDetails(ch, req.LogDetails)
		ch <- 1
	}
	utils.ToJson(w, res)
}

// Deletes 删除
func (c *examLog) Deletes(r *http.Request, w http.ResponseWriter) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get(utils.Token)
	userInfo := sys_serv.GetUserInfo(token)
	if userInfo == nil {
		utils.ToJson(w, utils.NoLogin)
		return
	}
	req := &exam_mod.ExamLogDelsReq{}
	// 将请求的参数转换为请求结构体
	if err := parse.Parse(r, req); err != "" {
		utils.ToJson(w, &utils.ResJson{Code: utils.ParamErr.Code, Msg: err})
		return
	}
	// 过滤关键参数值中的非法字符
	req.Id = utils.InputFilter(req.Id, true)
	res := exam_serv.ExamLogServ.Deletes(req.Id)
	if res.Code == utils.Succeed.Code {
		ch := make(chan int)
		go exam_serv.ExamLogServ.DelDetails(ch, req.Id)
		ch <- 1
		logReq := &sys_mod.SysLogSaveReq{UserId: userInfo.UserId, MenuCode: utils.ExamLog, IpAddr: userInfo.ClientIp, Kind: 2}
		sys_serv.SysLogServ.Add(logReq)
	}
	utils.ToJson(w, res)
}

// One 获取详情
func (c *examLog) One(r *http.Request, w http.ResponseWriter) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get(utils.Token)
	userInfo := sys_serv.GetUserInfo(token)
	if userInfo == nil {
		utils.ToJson(w, utils.NoLogin)
		return
	}
	// 过滤关键参数值中的非法字符
	u := r.URL.Query()
	if u == nil {
		utils.ToJson(w, utils.ParamErr)
		return
	}
	logId := u.Get("logId")
	// 过滤关键参数值中的非法字符
	logId = utils.InputFilter(logId, true)
	if logId == "" || len(logId) != 21 {
		utils.ToJson(w, utils.ParamErr)
		return
	}
	res := exam_serv.ExamLogServ.One(logId)
	if res.Code == utils.Succeed.Code {
		qstRes := exam_serv.ExamLogServ.ListLogQsts(logId)
		if qstRes.Code == utils.Succeed.Code {
			optRes := exam_serv.ExamLogServ.ListLogOpts(logId)
			for _, qst := range qstRes.Data.([]map[string]any) {
				qst["optList"] = make([]map[string]any, 0)
				for _, opt := range optRes.Data.([]map[string]any) {
					if qst["qstId"] == opt["qstId"] {
						qst["optList"] = append(qst["optList"].([]map[string]any), opt)
					}
				}
			}
			res.Data.(map[string]any)["qstList"] = qstRes.Data
		}
	}
	utils.ToJson(w, res)
}

// Page 获取分页列表
func (c *examLog) Page(r *http.Request, w http.ResponseWriter) {
	// 通过头部请求的token获取用户信息
	token := r.Header.Get(utils.Token)
	userInfo := sys_serv.GetUserInfo(token)
	if userInfo == nil {
		utils.ToJson(w, utils.NoLogin)
		return
	}
	// 过滤关键参数值中的非法字符
	u := r.URL.Query()
	if u == nil {
		utils.ToJson(w, utils.ParamErr)
		return
	}
	examId := u.Get("examId")
	keywords := u.Get("keywords")
	limits := u.Get("limit")
	offsets := u.Get("offset")
	examId = utils.InputFilter(examId, true)
	keywords = utils.InputFilter(keywords, false)
	limits = utils.InputFilter(limits, true)
	offsets = utils.InputFilter(offsets, true)
	limit := parse.Str2u8(limits)
	offset := parse.Str2u32(offsets)
	// 先统计信息的数量
	req := &exam_mod.ExamLogPageReq{ExamId: examId, Keywords: keywords}
	res := exam_serv.ExamLogServ.Count(req)
	if res.Code == utils.Succeed.Code {
		dto := &exam_mod.ExamLogPageRes{Total: res.Data.(map[string]any)["nums"].(int64)}
		// 再查询具体的信息列表
		req.Limit = limit
		req.Offset = offset
		if res = exam_serv.ExamLogServ.Page(req); res.Code == utils.Succeed.Code {
			dto.List = res.Data
			utils.ToJson(w, &utils.ResJson{Code: res.Code, Msg: res.Msg, Data: dto})
			return
		}
	}
	utils.ToJson(w, utils.NoData)
}

// HasTested 判断是否已答过题
func (c *examLog) HasTested(r *http.Request, w http.ResponseWriter) {
	req := &exam_mod.WorkerInfo{}
	// 将请求的参数转换为请求结构体
	if err := parse.Parse(r, req); err != "" {
		utils.ToJson(w, &utils.ResJson{Code: utils.ParamErr.Code, Msg: err})
		return
	}
	// 过滤关键参数值中的非法字符
	req.RealName = utils.InputFilter(req.RealName, true)
	req.WorkNo = utils.InputFilter(req.WorkNo, true)
	req.DeptName = utils.InputFilter(req.DeptName, true)
	res := exam_serv.ExamLogServ.HasTested(req)
	utils.ToJson(w, res)
}

// UserDetail 获取员工答题详情
func (c *examLog) UserDetail(r *http.Request, w http.ResponseWriter) {
	// 过滤关键参数值中的非法字符
	u := r.URL.Query()
	if u == nil {
		utils.ToJson(w, utils.ParamErr)
		return
	}
	logId := u.Get("logId")
	// 过滤关键参数值中的非法字符
	logId = utils.InputFilter(logId, true)
	if logId == "" || len(logId) != 21 {
		utils.ToJson(w, utils.ParamErr)
		return
	}
	res := exam_serv.ExamLogServ.One(logId)
	if res.Code == utils.Succeed.Code {
		qstRes := exam_serv.ExamLogServ.ListLogQsts(logId)
		if qstRes.Code == utils.Succeed.Code {
			optRes := exam_serv.ExamLogServ.ListLogOpts(logId)
			for _, qst := range qstRes.Data.([]map[string]any) {
				qst["optList"] = make([]map[string]any, 0)
				for _, opt := range optRes.Data.([]map[string]any) {
					if qst["qstId"] == opt["qstId"] {
						qst["optList"] = append(qst["optList"].([]map[string]any), opt)
					}
				}
			}
			res.Data.(map[string]any)["qstList"] = qstRes.Data
		}
	}
	utils.ToJson(w, res)
}

// Export 导出试卷详情
func (c *examLog) Export(r *http.Request, w http.ResponseWriter) {
	req := &exam_mod.ExamLogExportReq{}
	// 将请求的参数转换为请求结构体
	if err := parse.Parse(r, req); err != "" {
		utils.ToJson(w, &utils.ResJson{Code: utils.ParamErr.Code, Msg: err})
		return
	}
	logId := req.LogId
	// 过滤关键参数值中的非法字符
	logId = utils.InputFilter(logId, true)
	res := exam_serv.ExamLogServ.One(logId)
	if res.Code == utils.Succeed.Code {
		qstRes := exam_serv.ExamLogServ.ListLogQsts(logId)
		if qstRes.Code == utils.Succeed.Code {
			optRes := exam_serv.ExamLogServ.ListLogOpts(logId)
			for _, qst := range qstRes.Data.([]map[string]any) {
				qst["optList"] = make([]map[string]any, 0)
				for _, opt := range optRes.Data.([]map[string]any) {
					if qst["qstId"] == opt["qstId"] {
						qst["optList"] = append(qst["optList"].([]map[string]any), opt)
					}
				}
			}
			res.Data.(map[string]any)["qstList"] = qstRes.Data
		}
		newName := res.Data.(map[string]any)["realName"].(string) + "-" + res.Data.(map[string]any)["workNo"].(string) + ".docx"
		newPath := utils.ExpWord(newName, res.Data.(map[string]any))
		if _, err := os.Stat(newPath); err != nil || os.IsNotExist(err) {
			utils.ToJson(w, utils.DownloadErr)
			return
		}
		fb, err := os.ReadFile(newPath)
		if err != nil {
			utils.ToJson(w, utils.DownloadErr)
			return
		}
		w.Header().Add("content-type", "application/octet-stream")
		w.Header().Add("content-disposition", "attachment; filename="+url.QueryEscape(newName))
		w.Header().Add("Access-Control-Expose-Headers", "content-disposition")
		if _, err = w.Write(fb); err != nil {
			utils.ToJson(w, utils.DownloadErr)
		}
	}
	utils.ToJson(w, utils.NoData)
}

// ExportLs 导出试卷详情
func (c *examLog) ExportLs(r *http.Request, w http.ResponseWriter) {
	res := exam_serv.ExamLogServ.AllLog()
	if res.Code == utils.Succeed.Code {
		for _, log := range res.Data.([]map[string]any) {
			logId := log["logId"].(string)
			qstRes := exam_serv.ExamLogServ.ListLogQsts(logId)
			if qstRes.Code == utils.Succeed.Code {
				optRes := exam_serv.ExamLogServ.ListLogOpts(logId)
				for _, qst := range qstRes.Data.([]map[string]any) {
					qst["optList"] = make([]map[string]any, 0)
					for _, opt := range optRes.Data.([]map[string]any) {
						if qst["qstId"] == opt["qstId"] {
							qst["optList"] = append(qst["optList"].([]map[string]any), opt)
						}
					}
				}
				log["qstList"] = qstRes.Data
			}
			newName := log["realName"].(string) + "-" + log["workNo"].(string) + ".docx"
			utils.ExpWord(newName, log)
		}
		utils.ToJson(w, &utils.ResJson{Code: utils.Succeed.Code, Msg: "导出成功"})
		return
	}
	utils.ToJson(w, utils.NoData)
}
